package main.observer.pattern.Demo3;

import java.util.ArrayList;
import java.util.List;


/**
 * Created by DELL
 * Date: 2019/9/27.
 * Time: 8:22
 */
interface IObserver{
    void update(String s, int i);
}

class Observer1 implements IObserver {

    @Override
    public void update(String s, int i) {
        System.out.println("Observer1:myValue in" + s + " subject is now :" + i);
    }
}

class Observer2 implements IObserver {

    @Override
    public void update(String s, int i) {
        System.out.println("Observer2: Observers ->myValue  is changed in :" + s +" to : " + i);
    }
}

class Observer3 implements IObserver {

    @Override
    public void update(String s, int i) {
        System.out.println("Observer3 is observing : myValue  is changed in :" + s +" to : " + i);
    }
}

interface ISubject {
    void register(IObserver observer);
    void unregister(IObserver observer);
    void notifyObservers(int i);
}

class Subject1 implements ISubject {
    private int myValue;
     List<IObserver> observersList = new ArrayList<IObserver>();

    public int getMyValue() {
        return myValue;
    }

    public void setMyValue(int myValue) {
        this.myValue = myValue;
        notifyObservers(myValue);
    }

    @Override
    public void register(IObserver observer) {
        observersList.add(observer);
    }

    @Override
    public void unregister(IObserver observer) {
        observersList.remove(observer);
    }

    @Override
    public void notifyObservers(int updateValue) {
        for (int i = 0; i < observersList.size(); i++) {
            observersList.get(i).update(this.getClass().getSimpleName(),updateValue);
        }
    }
}

class Subject2 implements ISubject {
    private int myValue;
    List<IObserver> observersList = new ArrayList<IObserver>();

    public int getMyValue() {
        return myValue;
    }

    public void setMyValue(int myValue) {
        this.myValue = myValue;
        notifyObservers(myValue);
    }

    @Override
    public void register(IObserver observer) {
        observersList.add(observer);
    }

    @Override
    public void unregister(IObserver observer) {
        observersList.remove(observer);
    }

    @Override
    public void notifyObservers(int updateValue) {
        for (int i = 0; i < observersList.size(); i++) {
            observersList.get(i).update(this.getClass().getSimpleName(),updateValue);
        }
    }
}

class ObserverPatternEx {
    public static void main(String[] args) {

        System.out.println("***Observer Pattern Demo***\n");

        Subject1 sub1 = new Subject1();
        Subject2 sub2 = new Subject2();

        Observer1 observer1 = new Observer1();
        Observer2 observer2 = new Observer2();
        Observer3 observer3 = new Observer3();

        //Observer1 and Observer2 registers to //Subject1
        sub1.register(observer1);
        sub1.register(observer2);
        //Observer2 and Observer3 registers to //Subject2
        sub2.register(observer2);
        sub2.register(observer3);

        //set new value to Subject 1
        sub1.setMyValue(50);
        System.out.println();

        //set new value to Subject 2
        sub2.setMyValue(250);
        System.out.println();
        System.out.println();
        //unregister Observer2 from Suject1
        sub1.unregister(observer2);
        // Set new Value to Subject & only  //Observer1 is notified
        sub1.setMyValue(550);
        System.out.println("");
        //Ob2 can still notice change in //Subject2
        sub2.setMyValue(750);
    }

}

